'use strict'

const xlsx = require('node-xlsx')
const URL = require('url')

const { ApiController } = require('jax')

class AdminController extends ApiController {
  // 模型
  get Model() {
    return this.ctx.model.Admin
  }

  // 必填字段
  get required() {
    const keys = ['nickname', 'username', 'roleId']

    if (this.isNew) keys.push('password')

    return keys
  }

  // 匹配查询
  get include() {
    return [...this.required, 'isOpen', 'organizeId', 'password', 'mobile']
  }

  // 返回JSON字段
  get json() {
    const keys = this.include.filter((key) => key != 'password')
    return [...keys, 'id', 'createdAt', 'mobile']
  }

  // 超级管理员
  get isSuperAdmin() {
    const { ctx, config } = this
    const { admin } = ctx.state
    const { SYSTEM_TYPE_ADMIN } = config.constant

    return admin.isAdmin && admin.systemType == SYSTEM_TYPE_ADMIN
  }

  // 批量查询
  get searchKey() {
    return ['sourceId', 'isOpen', 'nickname', 'username', 'roleId', 'mobile', 'organizeId', 'systemType']
  }

  // 模糊查询
  get likeKey() {
    return ['name']
  }

  // 查询前
  beforeIndex() {
    const { ctx } = this
    const { admin } = ctx.state
    const filter = {
      systemType: admin.systemType,
    }

    // 超级管理员
    if (!this.isSuperAdmin) {
      filter.systemType = admin.systemType
      filter.sourceId = admin.sourceId
    }

    return { filter }
  }

  // 创建前
  async beforeCreate() {
    const { config, ctx } = this
    const { ADMIN_PASSWORD } = config.constant
    const { body } = ctx.request
    const { admin } = ctx.state

    if (!body.roleId) throw '请选择角色'

    const adminRole = await ctx.model.AdminRole.findOne({ _id: body.roleId })
    if (!adminRole) throw '无效角色'

    // 超级管理员
    // if(admin.systemType == 'admin' && admin.isAdmin){
    //   if(!body.systemType) body.systemType = admin.systemType;
    // }else{
    //   if(!body.systemType) throw '账号绑定系统失败'
    // }

    // 设置默认密码
    if (!body.password || body.password == '') body.password = ADMIN_PASSWORD
    // if (!body.password) throw '请填写用户密码'

    // 超级管理员
    if (this.isSuperAdmin) {
      // 未传递systemType使用管理员自身systemType
      if (!body.systemType) body.systemType = admin.systemType
    } else {
      body.sourceId = admin.sourceId
      body.systemType = admin.systemType
    }
  }

  // 保存前
  async beforeSave() {
    const { ctx } = this
    const { md5 } = ctx.helper
    const { body } = ctx.request
    const id = ctx.params?.id || body.id

    // 非新增无法使用这两个字段
    if (!this.isNew) {
      delete body.sourceId
      delete body.systemType
    }

    // 账户去重
    if (body.username) await ctx.service.systemUser.verifyUsername(body.username, id)
    if (body.mobile) await ctx.service.systemUser.verifyMobile(body.mobile, id)

    // 修改用户角色对应系统
    // if (body.roleId) {
    //   await ctx.model.AdminRole.findOne({
    //     _id: body.roleId,
    //   }).then((adminRole) => {
    //     if (!adminRole) throw '无效角色'

    //     body.systemType = adminRole.systemType
    //     body.sourceId = admin.sourceId
    //   })
    // }

    // 密码加密
    if (body.password && body.password != '') body.password = md5(body.password)
  }

  // 格式化
  async formatData(admin) {
    const { ctx } = this
    const { helper } = ctx

    const [adminRole, adminOrganize] = await Promise.all([
      // 角色
      ctx.model.AdminRole.findOne({
        _id: admin.roleId,
      }),
      // 组织
      ctx.model.AdminOrganize.findOne({
        _id: admin.organizeId,
      }),
    ])

    const newItem = this.toJson(admin)

    if (adminRole) newItem.roleName = adminRole.roleName
    if (adminOrganize) newItem.organizeName = adminOrganize.organizeName
    // return helper.exclude(admin, ['password'])

    return newItem
  }

  // 密码修改
  async modifyPassword() {
    const { ctx } = this
    const { ajv, md5 } = ctx.helper
    const { body } = ctx.request

    ajv(body, {
      required: ['originalPassword', 'password'],
    })

    const user = await ctx.model.Admin.findOne({
      _id: ctx.state.admin.id,
    })

    if (!user) throw '无效用户'

    if (user.password != md5(body.originalPassword)) {
      throw '原始密码不正确'
    }

    user.password = md5(body.password)
    await user.save()

    ctx.body = {
      code: 0,
      msg: '密码修改成功',
    }
  }

  // 用户权限
  async userAuth() {
    const { ctx } = this
    const { admin } = ctx.state

    ctx.state.data = await this.service.systemUser.getRoleAuth(admin.roleId)
  }

  // 导入用户
  async importUser() {
    const { ctx } = this
    const { config } = ctx
    const { url } = ctx.request.body

    const filename = config.uploadDir + URL.parse(url).path

    const workSheetsFromFile = xlsx.parse(filename)
    if (workSheetsFromFile) {
      const data = workSheetsFromFile[0].data

      for (let i = 0; i < data.length; i++) {
        if (i == 0) continue

        const [name, mobile] = data[i]

        // await ctx.model.User.replace({
        //     where: {
        //         idCardNo
        //     },
        //     data: {
        //         name,
        //         idCardNo,
        //         subject,
        //         updateTime: new Date(),
        //         isOepn: true
        //     }
        // })
      }
    }

    ctx.body = {
      code: 0,
      msg: '导入成功',
    }
  }

  /**
   * @api {post} /api/system/user/reset-password [用户] 重置密码
   * @apiDescription 重置密码
   * @apiUse AdminCommon
   * @apiGroup User
   * 
   * @apiBody {Number} adminId 用户ID
   * 
   * @apiSuccessExample {json} Success-Response:
    {
        "code": 0,
        "msg": "成功",
    }
   */
  async resetPassword() {
    const { ctx, config } = this
    const { md5 } = ctx.helper
    const { admin } = ctx.state
    const { body } = ctx.request
    const { ADMIN_PASSWORD } = config.constant

    if (!admin.isAdmin) throw '没有操作权限'

    await ctx.model.Admin.updateOne(
      {
        _id: body.adminId,
        systemType: admin.systemType,
      },
      { password: md5(ADMIN_PASSWORD) }
    )
  }

  // 绑定微信用户
  async setBindWeChat(ctx) {
    const { config } = ctx
    const { admin } = ctx.state
    const adminId = ctx.request.body.adminId

    // 查询合作商权限
    if (admin.roleId == 2) {
      const bindAdmin = await ctx.model.Admin.findOne({
        where: {
          id: adminId,
        },
      })

      if (bindadmin.sourceId) {
        await ctx.model.Hotel.findOne({
          where: {
            coId: admin.coId,
            id: bindadmin.sourceId,
          },
          notNull: '非合作商酒店',
        })
      }
    } else if (admin.roleId != 1) throw '无操作权限'

    const qrInfo = await ctx.model.QrLoginCode.create({
      code: nonce(10),
      userId: adminId,
      type: 0,
    })

    const bindUrl = `${config.host}/qr-login/bind/?code=${qrInfo.code}`

    ctx.body = {
      code: 0,
      msg: 'success',
      data: {
        qr: `/api/qr?text=` + encodeURIComponent(bindUrl),
      },
    }
  }

  // 获取绑定
  async getBindWeChat(ctx) {
    const { query } = ctx

    const userList = await ctx.model.QrLoginUser.findAll({
      where: {
        userId: query.adminId,
      },
    })

    ctx.body = {
      code: 0,
      msg: 'success',
      data: userList,
    }
  }

  // 用户信息
  async getUserInfo() {
    const { ctx } = this
    const { admin } = ctx.state

    ctx.state.data = await this.service.systemUser.getUserInfo(admin.id)
  }

  // 修改用户信息
  async setUserInfo() {
    const { ctx } = this
    const { helper } = ctx
    const { body } = ctx.request

    const admin = await ctx.model.Admin.findOne({
      _id: ctx.state.admin.id,
    })

    const data = helper.validate(body, {
      required: [],
      include: ['username', 'name', 'nickname', 'avatar'],
    })

    if (data.username) await this.service.systemUser.verifyUsername(data.username, admin.id)

    await ctx.model.Admin.updateOne(
      {
        _id: admin.id,
      },
      data
    )

    ctx.body = {
      code: 0,
      msg: 'success',
    }
  }
}

module.exports = AdminController
